package hr.tvz.lab.tom.malwaredb.entity;

import android.os.Parcel;
import android.os.Parcelable;

import com.raizlabs.android.dbflow.annotation.Column;
import com.raizlabs.android.dbflow.annotation.PrimaryKey;
import com.raizlabs.android.dbflow.annotation.Table;
import com.raizlabs.android.dbflow.structure.BaseModel;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import hr.tvz.lab.tom.malwaredb.ApplicationDatabase;

/**
 * MalwareObject Class.
 */
@Table(database = ApplicationDatabase.class)
public class MalwareObject extends BaseModel implements Parcelable {

    @Column
    @PrimaryKey
    private Integer id;
    @Column
    private String name;
    @Column
    private String type;
    @Column
    private String platform;
    @Column
    private String sourceLanguage;
    @Column
    private String fileType;
    @Column
    private Integer size;
    @Column
    private String author;
    @Column
    private String origin;
    @Column
    private String dateDiscovery;
    @Column
    private String aliases;
    @Column
    private String links;
    @Column
    private String description;

    public MalwareObject(Integer id, String name, String type, String platform, String sourceLanguage, String fileType, Integer size, String author, String origin, String dateDiscovery, String aliases, String links, String description) {
        this.id = id;
        this.name = name;
        this.type = type;
        this.platform = platform;
        this.sourceLanguage = sourceLanguage;
        this.fileType = fileType;
        this.size = size;
        this.author = author;
        this.origin = origin;
        this.dateDiscovery = dateDiscovery;
        this.aliases = aliases;
        this.links = links;
        this.description = description;
    }

    public MalwareObject() {
    }

    protected MalwareObject(Parcel in) {
        id = in.readInt();
        name = in.readString();
        type = in.readString();
        platform = in.readString();
        sourceLanguage = in.readString();
        fileType = in.readString();
        size = in.readInt();
        author = in.readString();
        origin = in.readString();
        dateDiscovery = in.readString();
        aliases = in.readString();
        links = in.readString();
        description = in.readString();
    }

    public static final Creator<MalwareObject> CREATOR = new Creator<MalwareObject>() {
        @Override
        public MalwareObject createFromParcel(Parcel in) {
            return new MalwareObject(in);
        }

        @Override
        public MalwareObject[] newArray(int size) {
            return new MalwareObject[size];
        }
    };

    @Override
    public int describeContents() {
        return id.hashCode()
                + name.hashCode()
                + type.hashCode()
                + platform.hashCode()
                + sourceLanguage.hashCode()
                + fileType.hashCode()
                + size.hashCode()
                + author.hashCode()
                + origin.hashCode()
                + dateDiscovery.hashCode()
                + aliases.hashCode()
                + links.hashCode()
                + description.hashCode();
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(id);
        dest.writeString(name);
        dest.writeString(type);
        dest.writeString(platform);
        dest.writeString(sourceLanguage);
        dest.writeString(fileType);
        dest.writeInt(size);
        dest.writeString(author);
        dest.writeString(origin);
        dest.writeString(dateDiscovery);
        dest.writeString(aliases);
        dest.writeString(links);
        dest.writeString(description);
    }

    /**
     * Debug toString function.
     * @return Every value in object.
     */
    @Override
    public String toString() {
        return "MalwareObject{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", type='" + type + '\'' +
                ", platform='" + platform + '\'' +
                ", sourceLanguage='" + sourceLanguage + '\'' +
                ", fileType='" + fileType + '\'' +
                ", size=" + size +
                ", author='" + author + '\'' +
                ", origin='" + origin + '\'' +
                ", dateDiscovery='" + dateDiscovery + '\'' +
                ", aliases='" + aliases + '\'' +
                ", links='" + links + '\'' +
                ", description='" + description + '\'' +
                '}';
    }

    /**
     * Converts aliases string object to list of string aliases.
     * DBFlow won't work with List<T> properly.
     * @return List of alias strings.
     */
    public List<String> getAliasList() {
        return Arrays.asList(aliases.split(";"));
    }

    /**
     * Get formatted string of aliases.
     * @return Aliases, formatted string.
     */
    public String getAliasesToString() {
        String aliases = "";
        List<String> aliasList = getAliasList();
        for (Integer i = 0; i < aliasList.size(); i++) {
            aliases += aliasList.get(i);
            if (i != aliasList.size() - 1) {
                aliases += ", ";
            }
        }
        return aliases;
    }

    /**
     * Converts links string object to list of string links.
     * DBFlow won't work with List<T> properly.
     * @return List of link strings.
     */
    public List<String> getLinksList() {
        return Arrays.asList(links.split(";"));
    }

    /**
     * Converts links string object to list of string links, filtered with type.
     * DBFlow won't work with List<T> properly.
     * @param type Type to filter links (media/link).
     * @return List of links strings.
     */
    public List<String> getLinksListByType(String type) {
        List<String> linkListByType = new ArrayList<>();
        String linkURL;
        String linkType;
        for (String link : getLinksList()) {
            // Temporary solution to display empty links.
            if (link.equals("None|none")) {
                if (type.contains("link")) {
                    linkListByType.add("No links available.");
                }
                return linkListByType;
            }
            linkURL = link.substring(0, link.indexOf("|"));
            linkType = link.substring(link.indexOf("|") + 1);
            if (linkType.equals(type)) {
                linkListByType.add(linkURL);
            }
        }
        return linkListByType;
    }

    // Getters, Setters, etc.

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getPlatform() {
        return platform;
    }

    public void setPlatform(String platform) {
        this.platform = platform;
    }

    public String getSourceLanguage() {
        return sourceLanguage;
    }

    public void setSourceLanguage(String sourceLanguage) {
        this.sourceLanguage = sourceLanguage;
    }

    public String getFileType() {
        return fileType;
    }

    public void setFileType(String fileType) {
        this.fileType = fileType;
    }

    public Integer getSize() {
        return size;
    }

    public void setSize(Integer size) {
        this.size = size;
    }

    public String getOrigin() {
        return origin;
    }

    public void setOrigin(String origin) {
        this.origin = origin;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getDateDiscovery() {
        return dateDiscovery;
    }

    public void setDateDiscovery(String dateDiscovery) {
        this.dateDiscovery = dateDiscovery;
    }

    public String getAliases() {
        return aliases;
    }

    public void setAliases(String aliases) {
        this.aliases = aliases;
    }

    public String getLinks() {
        return links;
    }

    public void setLinks(String links) {
        this.links = links;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}
